use egui::{Pos2, Rangef, Rect, Scene};

use crate::{graph::{Graph, GraphViewer}, node::NodeViewer};

pub struct FakViewer<T> {
    graph_viewer:Box<dyn GraphViewer<T>>,
    node_viewer:Box<dyn NodeViewer<T>>,
    graph_data:Option<Graph<T>>,
}

impl <T> FakViewer<T> {
    pub fn new(graph_viewer:Box<dyn GraphViewer<T>>, node_viewer:Box<dyn NodeViewer<T>>) -> Self {
        FakViewer {
            graph_viewer,
            node_viewer,
            graph_data:None,
        }
    }

    pub fn with(self, graph:Graph<T>) -> Self {
        FakViewer {
            graph_data:Some(graph),
            ..self
        }
    }

    pub fn set_graph(&mut self, graph:Graph<T>) {
        self.graph_data = Some(graph);
    }

}

impl <T> FakViewer<T> {
    pub fn show(&mut self, ui:&mut egui::Ui) {
        let Some(ref mut graph) = self.graph_data else {
            return;
        };

        // self.graph_viewer.draw_background(graph, ui, ui.max_rect());
        // self.graph_viewer.draw_nodes(graph, ui, self.node_viewer.as_mut());
        
        let mut scene_rect = if let Some(rect) = graph.last_rect {
            rect
        } else {
            let available_size = ui.available_size();
            Rect::from_two_pos(Pos2::ZERO, Pos2::new(available_size.x, available_size.y))
        };
        let scene = Scene::new().zoom_range(Rangef::new(0.1, 10.0));
        scene.show(ui, &mut scene_rect, |ui| {
            self.graph_viewer.draw_background(graph, ui, ui.max_rect());
            self.graph_viewer.draw_nodes(graph, ui, self.node_viewer.as_mut());
        });
        graph.last_rect = Some(scene_rect);
    }
}
